import subprocess
import os
import getpass
import platform

def install_vscode_extensions():
    """
    安装预定义的 VSCode 扩展。

    该函数尝试安装一组预定义的 VSCode 扩展。它首先检查是否找到了 VSCode 的路径，如果找到，则继续进行扩展安装。
    """
    extensions = [
        "ms-python.python",
        "ms-toolsai.jupyter",
        "ms-vscode.vscode-typescript-next",
        "esbenp.prettier-vscode"
    ]
    vscode_path = find_vscode_path()
    if vscode_path:
        for ext in extensions:
            try:
                subprocess.run([vscode_path, "--install-extension", ext], check=True)
            except subprocess.CalledProcessError as e:
                print(f"Failed to install extension {ext}: {e}")
    else:
        print("VSCode 未安装或其路径未添加到系统环境变量中。")

def configure_ssh_key(email, username):
    """
    配置 Git 使用的 SSH 密钥。

    该函数为用户生成 SSH 密钥对，并提示用户将公钥添加到 Gitee 账户中。如果密钥已存在，则不会覆盖现有密钥。
    """
    ssh_dir = os.path.expanduser("~/.ssh")
    if not os.path.exists(ssh_dir):
        os.makedirs(ssh_dir, mode=0o700)
    key_path = os.path.join(ssh_dir, "id_rsa")
    if not os.path.exists(key_path):
        passphrase = getpass.getpass("请输入 SSH 密钥的密码短语（留空则无密码）：")
        subprocess.run(["ssh-keygen", "-t", "rsa", "-b", "4096", "-C", email, "-f", key_path, "-N", passphrase], check=True)
        with open(os.path.join(ssh_dir, "id_rsa.pub"), "r") as f:
            print("请将以下 SSH 密钥添加到您的 Gitee 账户：")
            print(f.read())
    else:
        print("SSH 密钥已存在。")

def configure_git_user(email, username):
    """
    配置 Git 用户信息。

    该函数设置用户的邮箱和用户名用于 Git 配置，这些信息将用于所有 Git 操作。
    """
    try:
        subprocess.run(["git", "config", "--global", "user.email", email], check=True)
        subprocess.run(["git", "config", "--global", "user.name", username], check=True)
    except subprocess.CalledProcessError as e:
        print(f"配置 Git 用户信息失败: {e}")

def setup_git_repo(repo_url, project_path):
    """
    设置本地 Git 仓库。

    该函数从提供的 URL 克隆仓库，或者在指定路径初始化一个新的 Git 仓库。
    """
    if not os.path.exists(project_path):
        try:
            subprocess.run(["git", "clone", repo_url, project_path], check=True)
        except subprocess.CalledProcessError as e:
            print(f"克隆仓库失败: {e}")
            return False
    else:
        os.chdir(project_path)
        if not os.path.exists(".git"):
            try:
                subprocess.run(["git", "init"], check=True)
                subprocess.run(["git", "remote", "add", "origin", repo_url], check=True)
            except subprocess.CalledProcessError as e:
                print(f"初始化 Git 仓库失败: {e}")
                return False
        else:
            print("项目目录已经是 Git 仓库。")
    
    # 验证远程仓库配置
    try:
        remotes = subprocess.check_output(["git", "remote", "-v"]).decode('utf-8').strip()
        print("远程仓库配置：")
        print(remotes)
    except subprocess.CalledProcessError as e:
        print(f"验证远程配置失败: {e}")
        return False
    
    return True

def commit_and_push_code(commit_message, no_verify=False):
    """
    提交并推送代码到远程 Git 仓库。

    该函数将所有更改加入暂存区，使用提供的提交信息进行提交，并推送到远程仓库。可以选择绕过提交前的钩子。
    """
    if not commit_message.strip():
        print("提交信息不能为空。")
        return

    try:
        subprocess.run(["git", "add", "."], check=True)
        subprocess.run(["git", "commit", "-m", commit_message] + (["--no-verify"] if no_verify else []), check=True)

        # 获取当前分支名称
        branch_name = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).strip().decode('utf-8')
        print(f"当前分支: {branch_name}")

        # 尝试推送代码
        try:
            subprocess.run(["git", "push", "-u", "origin", branch_name], check=True)
            print("代码提交并推送成功。")
        except subprocess.CalledProcessError as e:
            print(f"推送代码失败: {e}")
            print("尝试手动推送以获取更多信息：")
            print(f"git push -u origin {branch_name}")
            return

    except subprocess.CalledProcessError as e:
        print(f"提交和推送代码失败: {e}")

def find_vscode_path():
    """
    查找 VSCode 的安装路径。

    该函数检查常见的 VSCode 安装路径，并返回找到的路径。
    """
    common_paths = []
    if platform.system() == "Windows":
        common_paths = [
            r"C:\Users\{}\AppData\Local\Programs\Microsoft VS Code\Code.exe".format(os.getlogin()),
            r"C:\Program Files\Microsoft VS Code\Code.exe",
            r"C:\Program Files (x86)\Microsoft VS Code\Code.exe"
        ]
    elif platform.system() == "Darwin":  # macOS
        common_paths = ["/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code"]
    elif platform.system() == "Linux":
        common_paths = ["/usr/share/code/code", "/usr/bin/code"]

    for path in common_paths:
        if os.path.exists(path):
            return path
    return None

def main():
    """
    主函数，执行设置过程。

    该函数收集必要的配置信息，并调用其他函数来设置开发环境。
    """
    email = input("请输入您的 Gitee 邮箱：").strip()
    if not email:
        print("Gitee 邮箱不能为空。")
        return

    username = input("请输入您的 Gitee 用户名：").strip()
    if not username:
        print("Gitee 用户名不能为空。")
        return

    repo_url = input("请输入您的 Gitee 仓库 URL：").strip()
    if not repo_url:
        print("Gitee 仓库 URL 不能为空。")
        return

    project_path = input("请输入您的本地项目路径：").strip()
    if not project_path:
        print("本地项目路径不能为空。")
        return

    commit_message = input("请输入您的提交信息：").strip()
    if not commit_message:
        print("提交信息不能为空。")
        return

    no_verify = input("您是否要绕过提交前的钩子？(y/n): ").strip().lower() == 'y'

    print("开始安装 VSCode 扩展...")
    install_vscode_extensions()

    print("配置 SSH 密钥...")
    configure_ssh_key(email, username)

    print("配置 Git 用户信息...")
    configure_git_user(email, username)

    print("设置本地 Git 仓库...")
    if not setup_git_repo(repo_url, project_path):
        print("Git 仓库设置失败，请检查日志并重试。")
        return

    print("提交并推送代码...")
    commit_and_push_code(commit_message, no_verify)

if __name__ == "__main__":
    main()